---@class Utility_LB_Kill
local LB_U = require "packages.lb_kill_utility._base"

-- 字符串mark: @[string]xxxx
-- 翻译储存值，值可以是字符串，或者字符串或数值表
-- 若储存字符串，标记显示该字符串的翻译，若储存表，标记显示表元素个数
-- 字符串均会被翻译
Fk:addQmlMark {
  name = "string",
  how_to_show = function(name, value)
    if type(value) == "string" then
      return Fk:translate(value)
    elseif type(value) == "table" then
      return tostring(#value)
    end
    return " "
  end,
  qml_data = function(name, value, player)
    if type(value) == "table" then
      return table.map(value, function(str)
        return tostring(str) -- 转换数字
      end)
    end
    return value
  end,
  qml_path = "packages/lb_kill_utility/qml/MarkDetailBox"
}

-- 记录多名角色，脸上显示数量，点击查看角色信息（若后继以$开头则仅自己可见）
-- 传入值：角色ID
-- 将[chara]与[player]结合，在仅记录一名角色时在脸上显示武将名
Fk:addQmlMark {
  name = "player_chara",
  how_to_show = function(_, value)
    if type(value) == "string" then value = tonumber(value) end --- 实际访问的时候这里会出string
    if not value or type(value) ~= "table" then return " " end
    local to = Fk:currentRoom():getPlayerById(value[1])
    return (#value == 1 and to) and to:__touistring() or tostring(#value)
  end,
  qml_path = function(name, value, p)
    if Self:isBuddy(p) or not string.startsWith(name, "@[player_chara]$") then
      return "packages/utility/qml/PlayerBox"
    end
    return ""
  end,
}

-- 记录多名角色，脸上显示数量，点击查看角色信息与对应其的字符串或数字（若后继以$开头则仅自己可见）
-- 传入值：["角色ID"] = "字符串"或数字
Fk:addQmlMark {
  name = "player_string",
  how_to_show = function(_, value)
    if type(value) ~= "table" then return " " end
    local num = 0
    for _, _ in pairs(value) do
      num = num + 1
    end
    return num == 0 and "#hidden" or tostring(num)
  end,
  qml_data = function(name, value, player)
    if type(value) == "table" then
      local change = {}
      for id, data in pairs(value) do
        local list = { tonumber(id) }
        if type(data) == "table" then
          for _, val in pairs(data) do
            table.insert(list, val)
          end
        else
          table.insert(list, data)
        end
        table.insert(change, list)
      end
      return change
    end
  end,
  qml_path = function(name, value, p)
    if Self:isBuddy(p) or not string.startsWith(name, "@[player_string]$") then
      return "packages/lb_kill_utility/qml/PlayerBox"
    end
    return ""
  end,
}

---@param player Player
local get_skill_players = function(value, player)
  local list = {}
  if type(value) == "table" and value.name then
    local skel = Fk.skill_skels[value.name]
    if skel and player:hasSkill(skel.name, true, true) then
      for _, id in ipairs(value.players) do
        if value.visible then
          local num = player:usedSkillTimes(skel.name, value.scope, tostring(id))
          if num > 0 then
            table.insert(list, { id, num > 0 and tostring(num) or "" })
          end
        else
          if not skel:withinBranchTimesLimit(player, tostring(id), value.scope) then -- 达到使用上限
            table.insert(list, id)
          end
        end
      end
    end
  end
  return list
end

-- 角色mark，与[player]相同，用于记录如“每回合每名角色限X次”中“达到X次”的角色，会因重置次数更新
-- 值为 { name = 技能名, scope = 范围, players = 玩家id数组, visible = 次数是否可见（显示大于0的次数） }
Fk:addQmlMark {
  name = "skill_players",
  how_to_show = function(name, value, player)
    local list = get_skill_players(value, player)
    return #list == 0 and "#hidden" or tostring(#list)
  end,
  qml_data = function(name, value, player)
    return get_skill_players(value, player)
  end,
  qml_path = function(name, value, player)
    local list = get_skill_players(value, player)
    if #list > 0 then
      return value.visible and "packages/lb_kill_utility/qml/PlayerBox" or "packages/utility/qml/PlayerBox"
    end
    return ""
  end,
}

---@param player Player
local get_skill_cardname = function(value, player)
  local list = {}
  if type(value) == "table" and value.name then
    local skel = Fk.skill_skels[value.name]
    if skel and player:hasSkill(skel.name, true, true) then
      for _, card_name in ipairs(value.all_names) do
        if not skel:withinBranchTimesLimit(player, card_name, value.scope) then -- 达到使用上限
          table.insert(list, card_name)
        end
      end
    end
  end
  return list
end

-- 卡牌牌名mark，与@$相同，用于记录如“每回合每种牌名限X次”中“达到X次”的牌名，会因重置次数更新
-- 值为 { name = 技能名, scope = 范围, all_names = 牌名数组 }
Fk:addQmlMark {
  name = "skill_cardname",
  how_to_show = function(name, value, player)
    local list = get_skill_cardname(value, player)
    return #list == 0 and "#hidden" or tostring(#list)
  end,
  qml_data = function(name, value, player)
    return get_skill_cardname(value, player)
  end,
  qml_path = function(name, value, player)
    local list = get_skill_cardname(value, player)
    return #list == 0 and "" or "packages/utility/qml/ViewPile"
  end,
}

---@param player Player
local get_skill_choices = function(value, player)
  local list, list_num = {}, {}
  local num_list = { "①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "⑩" }
  if type(value) == "table" and value.name then
    local skel = Fk.skill_skels[value.name]
    if skel and player:hasSkill(skel.name, true, true) then
      for i, choice_ in ipairs(value.choices) do
        if i > 10 then break end
        if type(choice_) == "table" then
          local choice, choice_num = table.unpack(choice_)
          if choice and skel:withinBranchTimesLimit(player, choice, value.scope) then -- 与skill_cardname不同，这是显示未达到使用上限的项
            table.insert(list, choice)
            table.insert(list_num, choice_num and Fk:translate(choice_num) or num_list[i])
          end
        end
      end
    end
  end
  return list, list_num
end

-- 选项mark，用于记录如每项限X次的技能，会因重置次数更新，最多支持10项
-- 值为 { name = 技能名, scope = 范围, choices = 选项数组, sep = 分隔字符 }
-- 选项值为 {"选项", "选项序号"} 选项序号可以自定义（会被翻译），为空则是带圈数字①②③④⑤
Fk:addQmlMark {
  name = "skill_choices",
  how_to_show = function(name, value, player)
    local _, num_list = get_skill_choices(value, player)
    return #num_list == 0 and "#hidden" or table.concat(num_list, value.sep)
  end,
  --[[  -- 有空再加上展开翻译
  qml_data = function(name, value, player)
    return get_skill_choices(value, player)
  end,
  qml_path = function(name, value, player)
    local list = get_skill_choices(value, player)
    return #list == 0 and "" or "packages/utility/qml/ViewPile"
  end,
  --]]
}

Fk:addQmlMark {
  name = "skills",
  how_to_show = function(_, value)
    if type(value) == "string" then
      return Fk:translate(value)
    elseif type(value) == "table" then
      local list = {}
      for _, val in ipairs(value) do
        local val_list = val
        if type(val) == "table" then
          val_list = val[1]
        end
        table.insert(list, val_list)
      end
      if #list > 0 then
        return #list == 1 and Fk:translate(list[1]) or tostring(#list)
      end
    end
    return "#hidden"
  end,
  qml_data = function(name, value, player)
    local list = {}
    if type(value) == "string" then
      table.insert(list, { value, 0 })
    elseif type(value) == "table" then
      for _, val in ipairs(value) do
        local val_list = val
        if type(val) == "string" then
          val_list = { val, 0 } -- 默认点亮
        end
        table.insert(list, val_list)
      end
    end
    return list
  end,
  qml_path = "packages/lb_kill_utility/qml/SkillMarkDetailBox"
}

-- 视为装备mark
Fk:addQmlMark {
  name = "VirtualEquip",
  how_to_show = function(name, value, player)
    local list = LB_U.hasVirtualEquip(player)
    if #list == 0 then
      return "#hidden"
    end
    return #list > 1 and tostring(#list) or Fk:translate(list[1])
  end,
  qml_data = function(name, value, player)
    return LB_U.hasVirtualEquip(player)
  end,
  qml_path = function(name, value, player)
    local list = LB_U.hasVirtualEquip(player)
    return #list == 0 and "" or "packages/utility/qml/ViewPile"
  end,
}
